<?php
/**
 * @author renjianhong
 * @date 2021-10-26
 */
namespace Modules\Order\Services\Api;

use App\Models\Area;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Modules\Order\Entities\BaseModel;
use Modules\Order\Entities\Order;
use Modules\Order\Entities\Cart;
use Modules\Order\Entities\GoodsCat;
use Modules\Order\Entities\GoodsCats;
use Modules\Order\Entities\Goods;
use Modules\Order\Entities\UserLevel;
use Modules\Order\Entities\OrderDetail;
use Modules\Order\Entities\MallSetting;
use Modules\Order\Entities\Coupon;
use Modules\Order\Entities\UserCoupon;
use Modules\Order\Entities\UserAddress;
use Modules\Order\Entities\PostageRules;
use Modules\Order\Entities\OfferPrice;
use Modules\Order\Entities\UserCapitalLog;
use Modules\Order\Entities\TerritorialLimitation;
use Modules\Order\Entities\FreeDeliveryRules;
use function Sodium\compare;

class OrderSubmitServices extends BaseService
{

    /**
     * @var Request
     */
    private $request;

    private $store;
    private $address;
    private $use_integral;
    private $payment;
    private $user;

    /**
     * @param Request $request
     */
    public function __construct(Request $request)
    {
        $this->request = $request;
        $this->store = MallSetting::first();
    }

    /**
     * 提交订单
     * @return
     */
    public function submit()
    {
        $param = $this->request->input();
        if(!$param['address_id']){
            throw new \Exception("地址不存在");
        }
        $user_id = $this->request->attributes->get('userId');
        if($user_id <= 0) throw new \Exception("用户不存在");
        $user = $this->getUserInfo($user_id);
        $mchListData = json_decode($param["mch_list"], true);

        $order_id_list = [];
        $level = $this->getUserLevel($user->user_level_id);
        //获取地址
        $this->address = UserAddress::where([['address_id','=',$param['address_id']],['user_id','=',$user->id],['is_delete','=',2]])->first();
        $address = $this->address;
        $this->use_integral = $param['use_integral'];
        $this->payment = $param['payment'];
        
        //开启事务
        DB::beginTransaction();
        foreach ($mchListData as &$mch) {
            //检查数据
            $checkMchData = $this->checkMchData($mch);
            if ($this->use_integral == 2) {
                $mch['integral'] = ['forehead' => 0, 'forehead_integral' => 0];
                $mch['give'] = 0;
            }
            if ($checkMchData['code'] == 1) {
                return $checkMchData;
            }

            $payPrice = $this->getPayPrice($mch);

            $order = new Order();
            $order->user_id = $user->id;
            $order->pay_price = $payPrice;
            $order->order_no = $this->getOrderNo();
            if (isset($mch['picker_coupon']) && !empty($mch['picker_coupon'])) {
                $order->user_coupon_id = $mch['picker_coupon']['user_coupon_id'];
                $coupon = UserCoupon::query()->where(['user_coupon_id' => $order->user_coupon_id])->first();
                if($coupon->coupon_type == 2) {
                    $newPayPrice = sprintf('%.2f', ($coupon->discount / 10) * $payPrice);
                    $order->coupon_sub_price = sprintf('%.2f', $payPrice - $newPayPrice);
                    $order->pay_price = $newPayPrice;
                } elseif($coupon->coupon_type == 1) {
//                    $order->coupon_sub_price = $mch['picker_coupon']['sub_price'];
                    $order->coupon_sub_price = $coupon->reduce_price;
                    $order->pay_price = sprintf('%.2f', $payPrice - $coupon->reduce_price);
                }

                // 查找优惠券优惠的商品
                $this->pickerGoods($mch);
            }
            if (isset($mch['plugin_type'])) {
                $order->type = $mch['plugin_type'];
            }

            $order->first_price = 0;
            $order->second_price = 0;
            
            $order->remark = isset($mch['content']) ? $mch['content'] : '';
            $order->is_offline = $mch['offline'];
            $order->integral = json_encode($mch['integral'], JSON_UNESCAPED_UNICODE);
            
            $order->mch_id = $mch['mch_id'];
            if ($mch['mch_id'] == 0) {
                $order->discount = $level['discount'];
            } else {
                $order->discount = 10;
            }
            if ($this->payment == 0) {
                $order->pay_name = '微信支付';
                $order->pay_code = 'wechat';
                $order->pay_type = 0;
            }
            if ($this->payment == 1) {
                $order->pay_name = '余额支付';
                $order->pay_code = 'balance';
                $order->pay_type = 1;
            }
            if ($this->payment == 2) {
                $order->pay_name = '货到付款';
                $order->pay_code = 'cash';
                $order->pay_type = 2;
            }
            if ($mch['offline'] == 0) {
                $order->address = $address->province . $address->city . $address->district . $address->detail;
                $order->mobile = $address->phone;
                $order->name = $address->name;
                $order->address_data = json_encode([
                    'province' => $address->province,
                    'city' => $address->city,
                    'district' => $address->district,
                    'detail' => $address->detail,
                ], JSON_UNESCAPED_UNICODE);
                $order->express_price = $mch['express_price'];
                $order->total_price = $mch['total_price'] + $mch['express_price'];
            } else {
                $order->name = $mch['offline_name'];
                $order->mobile = $mch['offline_mobile'];
                $order->shop_id = $mch['shop']['id'];
                $order->total_price = $mch['total_price'];
                $order->express_price = 0;
            }
            
            if ($order->save()) {

                // 处理订单生成之后其他相关数据
                $orderRes = $this->insertData($mch, $order,$user);
                
                //$printer_order = new PinterOrder($this->store_id, $order->id, 'order', 0);
                //$printer_order->print_order();
                $order_id_list[] = $order->id;
            } else {
                DB::rollBack();
                throw new \Exception("订单提交失败，请稍后重试");
            }
        }
        if (count($order_id_list) > 0) {
            DB::commit();
            if (count($order_id_list) > 1) {//多个订单合并
                return [
                    'order_id_list' => $order_id_list,
                ];
            } else {//单个订单
                return [
                    'order_id' => $order_id_list[0],
                ];
            }
        } else {
            DB::rollBack();
            throw new \Exception("订单提交失败，请稍后重试");
        }
    }

    /**
     * 检查数据
     * @param $mch
     * @return
     */
    private function checkMchData($mch)
    {
        if (empty($mch['goods_list'])) {
            return [
                'code' => 1,
                'msg' => '商品不存在或已删除'
            ];
        }
        $checkSendType = $this->checkSendType($mch);
        
        $checkCoupon = $this->checkCoupon($mch);
        
        $checkGoods = $this->checkGoods($mch);
        
        return ['code' => 0, 'msg' => 'success'];
    }

    /**
     * 检测商品相关
     * @param $mch
     * @return
     */
    private function checkGoods($mch)
    {
        foreach ($mch['goods_list'] as $goods) {
            
            $attr_id_list = [];
            foreach ($goods['attr_list'] as $item) {
                array_push($attr_id_list, $item['attr_id']);
            }
            $_goods = Goods::find($goods['goods_id']);
            if($_goods->type != 2){
                if (!$_goods->numSub($attr_id_list, $goods['num'],$_goods)) {
                    throw new \Exception("订单提交失败，商品“' . $_goods->name . '”库存不足");
                }
            }
        }
        return ['code' => 0, 'msg' => ''];
    }

    /**
     * 获取订单号
     * @return
     */
    public function getOrderNo()
    {
        $order_no = null;
        while (true) {
            $order_no = date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
            $exist_order_no = Order::where('order_no',$order_no)->exists();
            if (!$exist_order_no) {
                break;
            }
        }
        return $order_no;
    }

    /**
     * 检测优惠券是否可使用
     * @param $mch
     * @return
     */
    private function checkCoupon($mch)
    {
        if (empty($mch['picker_coupon'])) {
            return [
                'code' => 0,
                'msg' => ''
            ];
        }
        $ok = false;
        foreach ($mch['coupon_list'] as $item) {
            if ($item['user_coupon_id'] == $mch['picker_coupon']['user_coupon_id']) {
                $ok = true;
            }
        }
        if (!$ok) {
            throw new \Exception("该优惠券已过期");
        } else {
            return [
                'code' => 0,
                'msg' => ''
            ];
        }
    }

    /**
     * 检测发货方式
     * @param $mch
     * @return
     */
    private function checkSendType($mch)
    {
        if ($mch['mch_id'] == 0) {
            if ($mch['offline'] == 0) {
                if (!$this->address) {
                    throw new \Exception("收货地址不存在");
                }
                if ($mch['offer_rule'] && $mch['offer_rule']['is_allowed'] == 1) {
                    return [
                        'code' => 1,
                        'msg' => $mch['offer_rule']['msg']
                    ];
                }
                if ($mch['is_area'] == 1) {
                    throw new \Exception("所选地区自营商品暂时无货");
                }
            } else {
                if (isset($mch['shop']) == false) {
                    throw new \Exception("请选择自提门店");
                }
            }
        } else {
            if (!$this->address) {
                throw new \Exception("收货地址不存在");
            }
        }
        return ['code' => 0, 'msg' => ''];
    }

    /**
     * 获得实际支付金额
     * @param $mch
     * @return
     */
    private function getPayPrice($mch)
    {
        
        $payPrice = $mch['level_price'];
        if ($this->use_integral == 1) {
            $payPrice -= $mch['integral']['forehead'];
        }
        
//        if (isset($mch['picker_coupon'])) {
//            $pickerCoupon = $mch['picker_coupon'];
//            if ($pickerCoupon && $pickerCoupon['sub_price'] > 0) {
//                $payPrice -= $pickerCoupon['sub_price'];
//            }
//        }
        if ($mch['express_price'] > 0 && $mch['offline'] == 0) {
            $payPrice += $mch['express_price'];
        }

        return $payPrice >= 0 ? $payPrice : 0;
    }

    /**
     * 优惠券可优惠的商品总额计算
     * @return
     */
    private function pickerGoods(&$mch)
    {
        $totalPrice = 0;
        $pickerCoupon = $mch['picker_coupon'];
        if (empty($pickerCoupon)) {
            return;
        }
        
        foreach ($mch['goods_list'] as $item) {
            
            if ($pickerCoupon['apply_range'] == 3) {
                if($pickerCoupon['cat_id_list'] !== null){
                    $catIdList = $pickerCoupon['cat_id_list'];
                    if (array_intersect($item['cat_id'], $catIdList)) {
                        $totalPrice += $item['price'];
                        $mch['picker_coupon']['goods_id'][] = $item['goods_id'];
                    }
                }else{
                    $totalPrice += $item['price'];
                    $mch['picker_coupon']['goods_id'][] = $item['goods_id'];
                }
            } else if ($pickerCoupon['apply_range'] == 2) {
                if($pickerCoupon['goods_id_list'] !== null){
                    $goodsIdList = $pickerCoupon['goods_id_list'];
                    if (in_array($item['goods_id'], $goodsIdList)) {
                        $totalPrice += $item['price'];
                        $mch['picker_coupon']['goods_id'][] = $item['goods_id'];
                    }
                }else{
                    $totalPrice += $item['price'];
                    $mch['picker_coupon']['goods_id'][] = $item['goods_id'];
                }
            } else {
                $totalPrice += $item['price'];
                $mch['picker_coupon']['goods_id'][] = $item['goods_id'];
            }
        }
        $mch['picker_coupon']['total_price'] = $totalPrice;
    }

    /**
     * 下单成功后数据处理
     * @return
     */
    private function insertData($mch, $order,$user)
    {
        // 减去当前用户账户积分
        if ($mch['integral'] && $mch['integral']['forehead_integral'] > 0) {
            $user->integral -= $mch['integral']['forehead_integral'];
            if($user->integral < 0){
                throw new \Exception("积分不足");
            }
            $data['user_id'] = $user->id;
            $data['operate'] = 2;//扣除
            $data['type'] = 2;
            $data['amount'] = $mch['integral']['forehead_integral'];
            $data['description'] = '下单积分抵扣';
            UserCapitalLog::saveLog($data);
            
            $user->save();
        }

        // 计算商品相关
        $goods_list = $mch['goods_list'];
        
        foreach ($goods_list as $goods) {
            // 删除购物车
            if (isset($goods['cart_id'])) {
                $cart = Cart::where('id',$goods['cart_id'])->first();
                $cart->is_delete = 1;
                $cart->save();
            }
            
            $order_detail = new OrderDetail();
            $order_detail->order_id = $order->id;
            $order_detail->goods_id = $goods['goods_id'];
            $order_detail->goods_num = $goods['num'];
            if ($goods['is_level'] && $goods['is_level'] == 1) {
                $order_detail->is_level = $goods['is_level'];
            } else {
                $order_detail->is_level = 0;
            }
            $payPrice = $goods['level_price'];
            $goodsPrice = $goods['price'];
            if (isset($mch['picker_coupon']) && !empty($mch['picker_coupon'])) {
                if (in_array($goods['goods_id'], $mch['picker_coupon']['goods_id']) && $mch['picker_coupon']['total_price'] > 0) {
                    $pickerCouponSubPrice = doubleval($order->sub_price * doubleval($goods['price']) / $mch['picker_coupon']['total_price']);
                    $payPrice -= $pickerCouponSubPrice;
                }
                $user_coupon = UserCoupon::where('user_coupon_id',$mch['picker_coupon']['user_coupon_id'])->first();
                $user_coupon->is_use = 1;
                $user_coupon->save();
            }
            
            if ($goods['resIntegral'] && $goods['resIntegral']['forehead'] > 0) {
                $payPrice -= $goods['resIntegral']['forehead'];
            }
            $payPrice = $payPrice >= 0 ? $payPrice : 0;
            $goodsPrice = $goodsPrice >= 0 ? $goodsPrice : 0;
            $order_detail->goods_price = doubleval(sprintf('%.2f', floor($goodsPrice * 100) / 100));
            $order_detail->pay_price = doubleval(sprintf('%.2f', floor($payPrice * 100) / 100));
            $order_detail->is_delete = 0;
            $order_detail->goods_attr = json_encode($goods['attr_list'], JSON_UNESCAPED_UNICODE);
            $order_detail->goods_pic = $goods['goods_pic'];
            $order_detail->goods_name = $goods['goods_name'];
            if ($goods['give'] > 0 && $this->use_integral == 1) {
                $order_detail->integral = $goods['give'];
            }

            $attr_id_list = [];
            foreach ($goods['attr_list'] as $item) {
                array_push($attr_id_list, $item['attr_id']);
            }

            if (!$order_detail->save()) {
                throw new \Exception("订单提交失败，请稍后再重试");
            }
        }
        
        return [
            'code' => 0,
            'msg' => ''
        ];
    }
}